home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 007 / bytesc88.arc / FSCANF.C < prev    next >
Text File  |  1987-10-04  |  3KB  |  89 lines

  1. #define NOCCARGC  /* no argument count passing */
  2. /*
  3. ** Yes, that is correct.  Although these functions use an
  4. ** argument count, they do not call functions which need one.
  5. */
  6. #include stdio.h
  7. /*
  8. ** fscanf(fd, ctlstring, arg, arg, ...) - Formatted read.
  9. ** Operates as described by Kernighan & Ritchie.
  10. ** b, c, d, o, s, u, and x specifications are supported.
  11. ** Note: b (binary) is a non-standard extension.
  12. */
  13. fscanf(argc) int argc; {
  14.   int *nxtarg;
  15.   nxtarg = CCARGC() + &argc;
  16.   return (Uscan(*(--nxtarg), --nxtarg));
  17.   }
  18.  
  19. /*
  20. ** scanf(ctlstring, arg, arg, ...) - Formatted read.
  21. ** Operates as described by Kernighan & Ritchie.
  22. ** b, c, d, o, s, u, and x specifications are supported.
  23. ** Note: b (binary) is a non-standard extension.
  24. */
  25. scanf(argc) int argc; {
  26.   return (Uscan(stdin, CCARGC() + &argc - 1));
  27.   }
  28.  
  29. /*
  30. ** Uscan(fd, ctlstring, arg, arg, ...) - Formatted read.
  31. ** Called by fscanf() and scanf().
  32. */
  33. Uscan(fd,nxtarg) int fd, *nxtarg; {
  34.   char *carg, *ctl, *unsigned;
  35.   int  *narg, wast, ac, width, ch, cnv, base, ovfl, sign;
  36.   ac = 0;
  37.   ctl = *nxtarg--;
  38.   while(*ctl) {
  39.     if(isspace(*ctl)) {++ctl; continue;}
  40.     if(*ctl++ != '%') continue;
  41.     if(*ctl == '*') {narg = carg = &wast; ++ctl;}
  42.     else             narg = carg = *nxtarg--;
  43.     ctl += utoi(ctl, &width);
  44.     if(!width) width = 32767;
  45.     if(!(cnv = *ctl++)) break;
  46.     while(isspace(ch = fgetc(fd))) ;
  47.     if(ch == EOF) {if(ac) break; else return(EOF);}
  48.     ungetc(ch,fd);
  49.     switch(cnv) {
  50.       case 'c':
  51.         *carg = fgetc(fd);
  52.         break;
  53.       case 's':
  54.         while(width--) {
  55.           if((*carg = fgetc(fd)) == EOF) break;
  56.           if(isspace(*carg)) break;
  57.           if(carg != &wast) ++carg;
  58.           }
  59.         *carg = 0;
  60.         break;
  61.       default:
  62.         switch(cnv) {
  63.           case 'b': base =  2; sign = 1; ovfl = 32767; break;
  64.           case 'd': base = 10; sign = 0; ovfl =  3276; break;
  65.           case 'o': base =  8; sign = 1; ovfl =  8191; break;
  66.           case 'u': base = 10; sign = 1; ovfl =  6553; break;
  67.           case 'x': base = 16; sign = 1; ovfl =  4095; break;
  68.           default:  return (ac);
  69.           }
  70.         *narg = unsigned = 0;
  71.         while(width-- && !isspace(ch=fgetc(fd)) && ch!=EOF) {
  72.           if(!sign)
  73.             if(ch == '-') {sign = -1; continue;}
  74.             else sign = 1;
  75.           if(ch < '0') return (ac);
  76.           if(ch >= 'a')      ch -= 87;
  77.           else if(ch >= 'A') ch -= 55;
  78.           else               ch -= '0';
  79.           if(ch >= base || unsigned > ovfl) return (ac);
  80.           unsigned = unsigned * base + ch;
  81.           }
  82.         *narg = sign * unsigned;
  83.       }
  84.     ++ac;                          
  85.     }
  86.   return (ac);
  87.   }
  88.  
  89.